feat(api): add invoice V3 GET endpoint - #4541
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds billing invoice GET support across the TypeSpec API, JavaScript SDK, Go v3 handler path, and end-to-end tests. ChangesBilling invoice GET endpoint
Sequence Diagram(s)sequenceDiagram
participant Client
participant Server
participant billingService
participant ToAPIBillingInvoice
Client->>Server: GET /openmeter/billing/invoices/{invoiceId}
Server->>billingService: GetInvoiceById(...)
billingService-->>Server: billing.Invoice
Server->>ToAPIBillingInvoice: convert invoice
ToAPIBillingInvoice-->>Server: api.BillingInvoice
Server-->>Client: JSON response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
f7ca272 to
3e3c3d5
Compare
Greptile SummaryThis PR adds a v3
Confidence Score: 3/5The new invoice GET handler and TypeSpec definitions are structurally sound, but the accompanying rename of the managed_by → lifecycle_controller wire field in the charges response is a breaking change that could silently corrupt data for any existing v3 charges consumer. The charges handler change renames a JSON response field and removes an enum value at the wire level. Any client that was already reading the v3 charges endpoint and inspecting managed_by or matching on the value subscription will receive empty or wrong data without any error signal. This is compounded by the open issues carried over from earlier review rounds on convert.go (null detailed_lines, invalid status values for deleted invoices, unsupported invoice type masked as 404). The new invoice handler itself is well-structured and the e2e coverage is a positive addition. api/v3/handlers/customers/charges/convert.go (breaking wire change), api/v3/handlers/billinginvoices/convert.go (carries open issues from prior rounds), api/spec/packages/aip/src/customers/charges/charges.tsp (TypeSpec source of the breaking rename) Important Files Changed
|
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (3)
api/spec/packages/aip/src/invoices/invoice.tsp (1)
2-2: 📐 Maintainability & Code Quality | 🔵 TrivialDrop the
../invoices/index.tspimport frominvoice.tsp.
invoice.tspalready declaresnamespace Invoices, and this import forms a circular dependency withindex.tspwithout adding anything here.Suggested cleanup
-import "../invoices/index.tsp";🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/spec/packages/aip/src/invoices/invoice.tsp` at line 2, Remove the unnecessary `../invoices/index.tsp` import from `invoice.tsp`; the file already defines `namespace Invoices`, so the import adds no value and creates a circular dependency with `index.tsp`. Update `invoice.tsp` to keep only its own namespace and related declarations, and ensure nothing else in this file relies on symbols from `index.tsp`.e2e/billinginvoices_v3_test.go (1)
106-129: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftBroaden the assertions around the new invoice contract.
Nice start, but this happy path only checks a few top-level fields and the 404 case only checks
problem != nil. That leaves most of the new surface in this PR—like invoice line fields (quantity,unit_price), workflow payload, and the billing-specific problem body—effectively untested. Adding a representative line assertion plus a couple of concrete 404 problem-field checks would make this endpoint much harder to regress silently.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@e2e/billinginvoices_v3_test.go` around lines 106 - 129, Broaden the coverage in the v3 invoice GET tests by asserting the new contract fields exposed through GetBillingInvoice and AsBillingStandardInvoice. In the happy-path subtest, add checks for at least one invoice line’s quantity and unit_price, and verify the workflow payload is present and well-formed on the decoded standard invoice. In the 404 subtest, go beyond problem != nil by asserting concrete billing problem body fields on the returned problem object so the error shape is validated too.Source: Path instructions
api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts (1)
4-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPrefer an interface for the request shape.
This is a plain object contract, so
interfacekeeps it aligned with the repo’s TS conventions.Suggested fix
-export type GetInvoiceRequest = { +export interface GetInvoiceRequest { invoiceId: string }As per coding guidelines, "Prefer
interfacefor defining object shapes in TypeScript".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts` around lines 4 - 6, The request contract in GetInvoiceRequest is currently declared as a type alias, but this plain object shape should use an interface to match the repo’s TypeScript conventions. Update the GetInvoiceRequest definition in invoices.ts from a type alias to an interface, keeping the same invoiceId field so the request shape remains unchanged.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/spec/packages/aip-client-javascript/src/models/schemas.ts`:
- Around line 5188-5193: The invoice schema only includes standardInvoice in the
discriminated union, so credit_note payloads cannot be matched and the
credit-note branch is unreachable. Update the invoice
z.discriminatedUnion('type', ...) to include creditNoteInvoice alongside
standardInvoice, and ensure the credit note schema has its own unique
z.literal('credit_note') discriminator rather than sharing the standard type.
Keep the change localized to the invoice and creditNoteInvoice schema
definitions so the union resolves correctly by type.
- Around line 4758-4796: The invoice schema still excludes credit notes, so
update the union wiring around invoiceType and invoice to include credit-note
support. Add creditNoteInvoice to the invoice discriminated union alongside
standardInvoice, and extend invoiceType so it accepts the credit note variant as
well; use the existing invoiceType, invoice, standardInvoice, and
creditNoteInvoice symbols to locate the relevant schema definitions.
In `@api/spec/packages/aip-client-javascript/src/models/types.ts`:
- Around line 3311-3312: The `detailed_lines` field documentation in
`InvoiceLine` and `InvoiceLineInput` still mentions the removed `status` field,
so update both comments to describe the actual condition under which the array
is present. Use the `detailed_lines` property declarations in `types.ts` to
locate the stale wording and replace it with accurate SDK docs that no longer
reference `status`.
- Around line 2864-2865: The credit-note invoice variant is using the same
discriminator as StandardInvoice, which makes union narrowing and parsing
ambiguous. Update the credit-note branch in types.ts so the Invoice union has
its own unique discriminator value on the type field, and make sure any related
parsing/matching logic that keys off Invoice.type recognizes this new
credit-note discriminator alongside StandardInvoice.
In `@api/spec/packages/aip/src/invoices/invoice.tsp`:
- Around line 717-720: The documentation for the detailed sub-lines field refers
to a non-existent status property, so update the comment to describe the actual
presence rule instead. In the invoice schema around the detailed_lines
documentation, remove the outdated “Present when status is detailed or split”
wording and replace it with wording that matches the real model/implementation,
using the relevant field name as the source of truth.
- Around line 314-318: The doc comments on the invoice snapshot models are stale
and still refer to BillingParty inheritance even though the shapes are now
standalone. Update the summaries for the affected invoice snapshot types in
invoice.tsp, especially the snapshot-related declarations around
InvoiceCustomerSnapshot and the other cited snapshot model, so they describe the
actual standalone customer/billing snapshot data and any usage attribution
fields without mentioning extends or BillingParty.
- Around line 217-224: The invoice model’s `lines` field is underspecified for
the single-resource GET contract because it is marked optional even though
`BillingInvoice` always returns it. Update the `BillingInvoice`/`lines`
declaration in the invoice spec so the GET response reflects the actual
implementation by making `lines` required there, and only model omission
separately for any future list-shaped contract rather than weakening the current
`@visibility(Lifecycle.Read)` shape.
In `@api/v3/handlers/billinginvoices/convert.go`:
- Around line 25-37: The union dispatcher in convertInvoice only handles
billing.InvoiceTypeStandard, so it must be extended to map the other invoice
variants supported by the v3 contract. Update the switch on inv.Type() to add
the credit note case (and any other union members returned by GetInvoiceById),
convert each variant to its API shape, and populate the corresponding out union
setter instead of falling through to the unsupported invoice type error. Use the
existing helpers in this file, such as toAPIStandardInvoice and
out.FromBillingStandardInvoice, as the pattern for the new variant mappings.
In `@api/v3/handlers/billingprofiles/convert.go`:
- Around line 166-168: The address mapping in ToAPIBillingProfile is currently
guarded only by supplier.Address.Country, which causes valid supplier addresses
with line1, city, or postal_code but no country to be dropped. Update the
condition around the ToAPIAddress call so it maps any non-empty
supplier.Address, using the existing ToAPIAddress helper and the
supplier.Address fields as the source of truth, rather than requiring Country to
be set.
---
Nitpick comments:
In `@api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts`:
- Around line 4-6: The request contract in GetInvoiceRequest is currently
declared as a type alias, but this plain object shape should use an interface to
match the repo’s TypeScript conventions. Update the GetInvoiceRequest definition
in invoices.ts from a type alias to an interface, keeping the same invoiceId
field so the request shape remains unchanged.
In `@api/spec/packages/aip/src/invoices/invoice.tsp`:
- Line 2: Remove the unnecessary `../invoices/index.tsp` import from
`invoice.tsp`; the file already defines `namespace Invoices`, so the import adds
no value and creates a circular dependency with `index.tsp`. Update
`invoice.tsp` to keep only its own namespace and related declarations, and
ensure nothing else in this file relies on symbols from `index.tsp`.
In `@e2e/billinginvoices_v3_test.go`:
- Around line 106-129: Broaden the coverage in the v3 invoice GET tests by
asserting the new contract fields exposed through GetBillingInvoice and
AsBillingStandardInvoice. In the happy-path subtest, add checks for at least one
invoice line’s quantity and unit_price, and verify the workflow payload is
present and well-formed on the decoded standard invoice. In the 404 subtest, go
beyond problem != nil by asserting concrete billing problem body fields on the
returned problem object so the error shape is validated too.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0359abbf-2727-498a-a4b9-e1609084e610
⛔ Files ignored due to path filters (1)
api/v3/openapi.yamlis excluded by!**/openapi.yaml
📒 Files selected for processing (25)
api/spec/packages/aip-client-javascript/README.mdapi/spec/packages/aip-client-javascript/src/funcs/index.tsapi/spec/packages/aip-client-javascript/src/funcs/invoices.tsapi/spec/packages/aip-client-javascript/src/index.tsapi/spec/packages/aip-client-javascript/src/models/operations/invoices.tsapi/spec/packages/aip-client-javascript/src/models/schemas.tsapi/spec/packages/aip-client-javascript/src/models/types.tsapi/spec/packages/aip-client-javascript/src/sdk/invoices.tsapi/spec/packages/aip-client-javascript/src/sdk/sdk.tsapi/spec/packages/aip/src/invoices/index.tspapi/spec/packages/aip/src/invoices/invoice.tspapi/spec/packages/aip/src/invoices/operations.tspapi/spec/packages/aip/src/konnect.tspapi/spec/packages/aip/src/openmeter.tspapi/v3/api.gen.goapi/v3/handlers/billinginvoices/convert.goapi/v3/handlers/billinginvoices/error_encoder.goapi/v3/handlers/billinginvoices/get.goapi/v3/handlers/billinginvoices/handler.goapi/v3/handlers/billingprofiles/convert.goapi/v3/handlers/customers/charges/convert.goapi/v3/server/routes.goapi/v3/server/server.goe2e/billinginvoices_v3_test.goe2e/v3helpers_test.go
b99fc39 to
4cb8268
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/v3/server/server.go`:
- Around line 325-330: Resolve the merge conflict in server.go by removing the
conflict markers and keeping both handlers wired correctly. In the server setup
near plansHandler and billingInvoicesHandler, preserve the required
planshandler.New contract by passing config.UnitConfig.Enabled along with
resolveNamespace, config.PlanService, and
httptransport.WithErrorHandler(config.ErrorHandler), and also keep the
billingInvoicesHandler.New constructor with its namespace, billing service, and
error handler. Ensure the block compiles cleanly with both constructors intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: fe3ab63d-021d-4fec-b537-38031e2b8ddd
⛔ Files ignored due to path filters (1)
api/v3/openapi.yamlis excluded by!**/openapi.yaml
📒 Files selected for processing (25)
api/spec/packages/aip-client-javascript/README.mdapi/spec/packages/aip-client-javascript/src/funcs/index.tsapi/spec/packages/aip-client-javascript/src/funcs/invoices.tsapi/spec/packages/aip-client-javascript/src/index.tsapi/spec/packages/aip-client-javascript/src/models/operations/invoices.tsapi/spec/packages/aip-client-javascript/src/models/schemas.tsapi/spec/packages/aip-client-javascript/src/models/types.tsapi/spec/packages/aip-client-javascript/src/sdk/invoices.tsapi/spec/packages/aip-client-javascript/src/sdk/sdk.tsapi/spec/packages/aip/src/invoices/index.tspapi/spec/packages/aip/src/invoices/invoice.tspapi/spec/packages/aip/src/invoices/operations.tspapi/spec/packages/aip/src/konnect.tspapi/spec/packages/aip/src/openmeter.tspapi/v3/api.gen.goapi/v3/handlers/billinginvoices/convert.goapi/v3/handlers/billinginvoices/error_encoder.goapi/v3/handlers/billinginvoices/get.goapi/v3/handlers/billinginvoices/handler.goapi/v3/handlers/billingprofiles/convert.goapi/v3/handlers/customers/charges/convert.goapi/v3/server/routes.goapi/v3/server/server.goe2e/billinginvoices_v3_test.goe2e/v3helpers_test.go
✅ Files skipped from review due to trivial changes (2)
- api/spec/packages/aip-client-javascript/src/funcs/index.ts
- api/spec/packages/aip-client-javascript/src/models/operations/invoices.ts
🚧 Files skipped from review as they are similar to previous changes (21)
- api/v3/handlers/billinginvoices/error_encoder.go
- api/v3/handlers/billinginvoices/handler.go
- api/spec/packages/aip-client-javascript/src/sdk/invoices.ts
- api/spec/packages/aip/src/openmeter.tsp
- api/v3/server/routes.go
- api/v3/handlers/billingprofiles/convert.go
- api/v3/handlers/billinginvoices/get.go
- api/spec/packages/aip/src/invoices/operations.tsp
- api/spec/packages/aip-client-javascript/src/funcs/invoices.ts
- e2e/billinginvoices_v3_test.go
- api/spec/packages/aip-client-javascript/README.md
- api/spec/packages/aip/src/invoices/index.tsp
- api/spec/packages/aip/src/konnect.tsp
- api/v3/handlers/customers/charges/convert.go
- e2e/v3helpers_test.go
- api/spec/packages/aip-client-javascript/src/sdk/sdk.ts
- api/v3/handlers/billinginvoices/convert.go
- api/spec/packages/aip/src/invoices/invoice.tsp
- api/spec/packages/aip-client-javascript/src/index.ts
- api/spec/packages/aip-client-javascript/src/models/types.ts
- api/spec/packages/aip-client-javascript/src/models/schemas.ts
3188916 to
ae35a6e
Compare
ae35a6e to
39736aa
Compare
69a1621 to
4cc29fc
Compare
Overview
Fixes #(issue)
Notes for reviewer
Summary by CodeRabbit
Invoicessurface and aninvoices.getoperation to fetch invoices by ID.